<?php

namespace shisou\tpgii\handler;

use think\helper\Str;
use PhpOffice\PhpSpreadsheet\IOFactory;

class ParseExcel
{
    public function get()
    {
        $excel = root_path() . '/db.xlsx';

        $spreadsheet = IOFactory::load($excel);

        $sheet     = $spreadsheet->getActiveSheet();
        $highestRi = $sheet->getHighestDataRow();

        // tables
        $tables = [];

        for ($ri = 1; $ri <= $highestRi; $ri++) {
            // table start
            if (
                $sheet->getCell('B' . $ri)
                    ->getValue() == 'TABLE'
            ) {
                $table = [];

                $table['tableName']   = trim($sheet->getCell('C' . $ri)
                    ->getValue() ?: '');
                $table['tableNameCn'] = trim($sheet->getCell('D' . $ri)
                    ->getValue() ?: '');
                $table['remark']      = trim($sheet->getCell('G' . $ri)
                    ->getValue() ?: '');

                // skip the header rows
                $ri += 2;

                // loop attr rows
                for (; $ri <= $highestRi; $ri++) {
                    // table end
                    if (
                        $sheet->getCell('B' . $ri)
                            ->getValue() == ''
                    ) {
                        $tables[$table['tableName']] = $table;
                        break;
                    }

                    $col = trim($sheet->getCell('B' . $ri)
                        ->getValue() ?: '');

                    $colCn = trim($sheet->getCell('C' . $ri)
                        ->getValue() ?: '');

                    if (str_starts_with($colCn, '@')) {
                        $tmp = str_replace('@', '', $colCn);

                        $relation                 = [];
                        $relation['propertyType'] = Str::studly($tmp);
                        $relation['property']     = lcfirst(Str::camel(str_replace('_id', '', $col)));
                        $relation['get']          = Str::camel(str_replace('_id', '', $col));
                        $relation['class']        = Str::studly($tmp);
                        $relation['on']           = "'id' , '{$col}'";
                        $relation['has']          = 'hasOne';

                        $table['relations'][] = $relation;

                        if ($relation['property'] == 'parent') {
                            $relation                 = [];
                            $relation['propertyType'] = Str::studly($table['tableName']) . '[]';
                            $relation['property']     = 'children';
                            $relation['get']          = 'children';
                            $relation['class']        = Str::studly($table['tableName']);
                            $relation['on']           = "'parent_id' , 'id'";
                            $relation['has']          = 'hasMany';

                            $table['relations'][] = $relation;
                        }
                    }
                    if (str_ends_with($colCn, '@')) {
                        $tmp = str_replace('@', '', $colCn);

                        $relation                 = [];
                        $relation['propertyType'] = Str::studly($table['tableName']) . '[]';
                        $relation['property']     = lcfirst(Str::camel($table['tableName']) . 'List');
                        $relation['get']          = Str::camel($table['tableName']) . 'List';
                        $relation['class']        = Str::studly($table['tableName']);
                        $relation['on']           = "'{$col}' , 'id'";
                        $relation['has']          = 'hasMany';

                        $tables[$tmp]['relations'][] = $relation;
                    }

                    if (str_starts_with($colCn, '&')) {
                        $relation                 = [];
                        $relation['propertyType'] = Str::studly($table['tableName']);
                        $relation['property']     = lcfirst(Str::camel(str_replace('_id', '', $col)));
                        $relation['get']          = Str::camel($table['tableName']);
                        $relation['class']        = "";
                        $relation['on']           = "";
                        $relation['has']          = 'morphTo';
                        $table['relations'][]     = $relation;

                        $tmp = explode(',', $colCn);
                        foreach ($tmp as $k => $v) {
                            $relation          = [];
                            $relation['class'] = Str::studly($table['tableName']);

                            if (str_ends_with($v, '&')) {
                                $relation['propertyType'] = Str::studly($table['tableName']) . '[]';
                                $relation['property']     = lcfirst(Str::camel($table['tableName']) . 'List');
                                $relation['get']          = Str::camel($table['tableName']) . 'List';
                                $relation['has']          = 'morphMany';
                            } else {
                                $relation['property'] = lcfirst(Str::camel($table['tableName']));
                                $relation['get']      = Str::camel($table['tableName']);
                                $relation['class']    = Str::studly($table['tableName']);
                                $relation['has']      = 'morphOne';
                            }

                            $morphTable                         = str_replace('&', '', $v);
                            $relation['on']                     = "'" . $table['tableName'] . "','" . Str::studly($morphTable) . "'";
                            $tables[$morphTable]['relations'][] = $relation;
                        }
                    }

                    $tbCol           = [
                        'col'   => $col,
                        'colCn' => $colCn,
                        'type'  => trim($sheet->getCell('D' . $ri)
                            ->getValue() ?: ''),
                        'len'   => trim($sheet->getCell('E' . $ri)
                            ->getValue() ?: ''),
                        'key'   => trim($sheet->getCell('F' . $ri)
                            ->getValue() ?: ''),
                    ];
                    $table['cols'][] = $tbCol;
                }
            }
        }

        return $tables;
    }
}
